﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SnakeGame
{
    public class PlayerScore : IComparable
    {
        private string playerName;
        private int score;
        DateTime dateCreated;

        public PlayerScore(string playerName, int score)
        {
            this.PlayerName = playerName;
            this.Score = score;
            this.DateCreated = DateTime.Now;
        }

        public PlayerScore(string playerName, int score, DateTime dateCreated)
            : this(playerName, score)
        {
            this.DateCreated = dateCreated;
        }

        public string PlayerName
        {
            get
            {
                return this.playerName;
            }

            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("The name of the player cannot be null.");
                }

                this.playerName = value;
            }
        }

        public int Score
        {
            get
            {
                return this.score;
            }

            set
            {
                this.score = value;
            }
        }

        public DateTime DateCreated
        {
            get
            {
                return this.dateCreated;
            }

            private set
            {
                this.dateCreated = value;
            }
        }

        public int CompareTo(object obj)
        {
            PlayerScore otherPlayerScore = (PlayerScore)obj;

            int result = 0;

            if (otherPlayerScore == null)
            {
                throw new InvalidCastException(
                    "The player score could not be compared to an instance of System.Object.");
            }

            if (this.score < otherPlayerScore.score)
            {
                result = -1;
            }
            else if (this.score > otherPlayerScore.score)
            {
                result = 1;
            }

            return result;
        }

        public static PlayerScore Parse(string playerScore)
        {
            string name = playerScore.Substring(0, playerScore.IndexOf(' ')).Trim();

            int scoreStartIndex = playerScore.IndexOf(':') + 1;
            int scoreEndIntex = playerScore.IndexOf(',', scoreStartIndex);
            int scoreLength = scoreEndIntex - scoreStartIndex;
            string scoreAsString = playerScore.Substring(scoreStartIndex, scoreLength).Trim();
            int score;

            if (!int.TryParse(scoreAsString, out score))
            {
                throw new ArgumentException("Invalid player score string.");
            }

            int indexOfDateWord = playerScore.IndexOf("Date: ");
            int dateStartIndex = playerScore.IndexOf(':', indexOfDateWord) + 1;
            string dateAsString = playerScore.Substring(dateStartIndex).Trim();
            DateTime date = DateTime.Parse(dateAsString);

            PlayerScore parsedPlayerScore = new PlayerScore(name, score, date);

            return parsedPlayerScore;
        }

        public override string ToString()
        {
            string result = 
                string.Format("{0} : {1}, Date: {2}", this.playerName, this.score, this.dateCreated);

            return result;
        }

        public static bool operator <(PlayerScore firstPlayerScore, PlayerScore secondPlayerScore)
        {
            if (firstPlayerScore.CompareTo(secondPlayerScore) < 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool operator >(PlayerScore firstPlayerScore, PlayerScore secondPlayerScore)
        {
            if (firstPlayerScore.CompareTo(secondPlayerScore) > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
